package com.demo.crm.springboot3security.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.demo.crm.springboot3security.entity.User;
import com.demo.crm.springboot3security.security.CustomUserDetails;
import com.demo.crm.springboot3security.security.JwtTokenUtil;
import com.demo.crm.springboot3security.service.UserService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final JwtTokenUtil jwtTokenUtil;
    private final UserService userService;
    private final PasswordEncoder passwordEncoder;

    public AuthController(
            @Lazy AuthenticationManager authenticationManager,
            JwtTokenUtil jwtTokenUtil,
            UserService userService,
            @Lazy PasswordEncoder passwordEncoder) {
        this.authenticationManager = authenticationManager;
        this.jwtTokenUtil = jwtTokenUtil;
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
    }

    @PostMapping(value = "/login", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        log.info("Attempting login for user: {}", loginRequest.username());
        try {
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginRequest.username(), loginRequest.password())
            );

            CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
            String jwt = jwtTokenUtil.generateToken(userDetails);

            Map<String, Object> response = new HashMap<>();
            response.put("token", jwt);
            response.put("username", userDetails.getUsername());

            log.info("Login successful for user: {}", loginRequest.username());
            return ResponseEntity.ok(response);
        } catch (BadCredentialsException e) {
            log.error("Login failed for user: {}", loginRequest.username(), e);
            return ResponseEntity.status(401).body("用户名或密码错误");
        } catch (Exception e) {
            log.error("Login error for user: {}", loginRequest.username(), e);
            return ResponseEntity.status(500).body("登录过程中发生错误");
        }
    }

    @PostMapping(value = "/register", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
        log.info("Attempting registration for user: {}", registerRequest.username());
        try {
            // 检查用户名是否已存在
            // if (userService.findByUsername(registerRequest.username()).isPresent()) {
            if (userService.findByUsername(registerRequest.username()) != null) {
                log.warn("Registration failed - username already exists: {}", registerRequest.username());
                return ResponseEntity.badRequest().body("用户名已存在");
            }

            // 创建新用户
            User user = new User();
            user.setUsername(registerRequest.username());
            user.setPassword(passwordEncoder.encode(registerRequest.password()));
            user.setEnabled(true);

            userService.save(user);
            log.info("Registration successful for user: {}", registerRequest.username());
            return ResponseEntity.ok("注册成功");
        } catch (Exception e) {
            log.error("Registration error for user: {}", registerRequest.username(), e);
            return ResponseEntity.status(500).body("注册过程中发生错误");
        }
    }
}

record LoginRequest(String username, String password) {
}

record RegisterRequest(String username, String password) {
}